class_name ControllerComponent
extends BaseComponent

#region 属性
@export var controller:ControllerBase
@export var controller_additional_effects:Array[AdditionalEffect]
var key_action_signal_dict:Dictionary = {}
var controller_command_manager:ControllerCommandManager = ControllerCommandManager.new()
#endregion
#region 字段
#endregion
#region 信号
signal key_action_state_changed(key_action:GameEnum.KeyAction,key_action_state:GameEnum.KeyActionState)
#endregion

#region 基类方法
func init_component(args:Dictionary = {}):
	super(args)
	for key_action in GameEnum.KeyAction.values():
		key_action_signal_dict[key_action] = {}
		# 记录是否是当前帧刚变化到这个状态，只对Pressed和Released有效，用于下一帧自动切换到下一个状态
		key_action_signal_dict[key_action]["IsJustChanged"] = false
		key_action_signal_dict[key_action]["KeyActionState"] = GameEnum.KeyActionState.Idle
	if controller:
		controller.register_key_action_event(_on_controller_key_action_state_changed)
	controller_command_manager.init(self)
	Utils.array_call_method(controller_additional_effects,"init",{Target = entity,Owner = self})
	Utils.array_call_method(controller_additional_effects,"excute")
	key_action_state_changed.connect(on_key_action_state_changed)
#endregion
#region 公共方法
func press_key_action(key_action:GameEnum.KeyAction):
	if not key_action_signal_dict.has(key_action):
		return
	var item = key_action_signal_dict[key_action]
	if not item["KeyActionState"] == GameEnum.KeyActionState.Idle:
		return
	item["IsJustChanged"] = true
	item["KeyActionState"] = GameEnum.KeyActionState.Pressed
	key_action_state_changed.emit(key_action,item["KeyActionState"])
func release_key_action(key_action:GameEnum.KeyAction):
	if not key_action_signal_dict.has(key_action):
		return
	var item = key_action_signal_dict[key_action]
	if not item["KeyActionState"] == GameEnum.KeyActionState.Pressed and not item["KeyActionState"] == GameEnum.KeyActionState.Stay:
		return
	item["IsJustChanged"] = true
	item["KeyActionState"] = GameEnum.KeyActionState.Released
	key_action_state_changed.emit(key_action,item["KeyActionState"])
func detect_action_keys():
	for key_action in GameEnum.KeyAction.values():
		if not key_action_signal_dict.has(key_action):
			continue
		# 自动切换状态
		var item = key_action_signal_dict[key_action]
		if item["KeyActionState"] == GameEnum.KeyActionState.Pressed:
			if item["IsJustChanged"]:
				item["IsJustChanged"] = false
			else:
				_stay_key_action(key_action)
		elif item["KeyActionState"] == GameEnum.KeyActionState.Released:
			if item["IsJustChanged"]:
				item["IsJustChanged"] = false
			else:
				_idle_key_action(key_action)
		# Stay状态会每帧都触发Stay事件
		elif item["KeyActionState"] == GameEnum.KeyActionState.Stay:
			item["IsJustChanged"] = false
			key_action_state_changed.emit(key_action,item["KeyActionState"])
func get_controller() -> ControllerBase:
	return controller
func get_controller_command_manager() -> ControllerCommandManager:
	return controller_command_manager
func register_key_action_state_changed_event(callback:Callable):
	if not key_action_state_changed.is_connected(callback):
		key_action_state_changed.connect(callback)
func unregister_key_action_state_changed_event(callback:Callable):
	if key_action_state_changed.is_connected(callback):
		key_action_state_changed.disconnect(callback)
func on_key_action_state_changed(key_action:GameEnum.KeyAction,key_action_state:GameEnum.KeyActionState):
	var state_component:StateComponent = entity.get_component(StateComponent)
	if state_component:
		var state_chart:StateChart = state_component.get_state_chart_manager().chart
		if state_chart:
			state_chart.set_expression_property("Controller_" + Utils.get_enum_key_by_value(GameEnum.KeyAction,key_action),key_action_state)
#endregion
#region 私有方法
func _idle_key_action(key_action:GameEnum.KeyAction):
	if not key_action_signal_dict.has(key_action):
		return
	var item = key_action_signal_dict[key_action]
	if item["KeyActionState"] == GameEnum.KeyActionState.Idle:
		return
	item["IsJustChanged"] = false
	item["KeyActionState"] = GameEnum.KeyActionState.Idle
	key_action_state_changed.emit(key_action,item["KeyActionState"])
func _stay_key_action(key_action:GameEnum.KeyAction):
	if not key_action_signal_dict.has(key_action):
		return
	var item = key_action_signal_dict[key_action]
	if not item["KeyActionState"] == GameEnum.KeyActionState.Pressed:
		return
	item["IsJustChanged"] = false
	item["KeyActionState"] = GameEnum.KeyActionState.Stay
	key_action_state_changed.emit(key_action,item["KeyActionState"])
func _on_controller_key_action_state_changed(key_action:GameEnum.KeyAction,key_action_state:GameEnum.KeyActionState):
	if key_action_state == GameEnum.KeyActionState.Idle:
		release_key_action(key_action)
	elif key_action_state == GameEnum.KeyActionState.Pressed:
		press_key_action(key_action)
	elif key_action_state == GameEnum.KeyActionState.Released:
		release_key_action(key_action)
	var state_component:StateComponent = entity.get_component(StateComponent)
	if state_component:
		var state_chart:StateChart = state_component.get_state_chart_manager().chart
		if state_chart:
			state_chart.set_expression_property("Controller_" + Utils.get_enum_key_by_value(GameEnum.KeyAction,key_action),key_action_state)
#endregion
#region 生命周期函数
func _process(delta: float) -> void:
	if not inited:
		return
	if controller:
		controller.check_process()
	controller_command_manager.process()
	detect_action_keys()
func _physics_process(delta: float) -> void:
	if not inited:
		return
	# 开启移动
	var root = get_entity().root
	if root is CharacterBody2D:
		var vel_info = entity.entity_data.get_final_move_vel_info(delta)
		root.velocity = vel_info.FinalVel
		var attr:Attribute = entity.entity_data.find_attribute("Vel")
		if attr:
			attr.force_set_base_value(root.velocity)
		attr = entity.entity_data.find_attribute("BaseVel")
		if attr:
			attr.force_set_base_value(vel_info.BaseVel)
		# 记录StateManager需要的参数
		var state_component:StateComponent = entity.get_component(StateComponent)
		if state_component:
			var state_chart:StateChart = state_component.get_state_chart_manager().chart
			if state_chart:
				var property_name = "Runtime_{0}".format(["Speed"])
				var last_speed = state_chart.get_expression_property(property_name)
				if last_speed != entity.entity_data.get_attribute_value("Vel").length():
					state_chart.set_expression_property(property_name,entity.entity_data.get_attribute_value("Vel").length())
		root.move_and_slide()
	elif root is RigidBody2D:
		var vel_info = entity.entity_data.get_final_move_vel_info(delta)
		root.linear_velocity = vel_info.FinalVel
		var attr:Attribute = entity.entity_data.find_attribute("Vel")
		if attr:
			attr.force_set_base_value(root.linear_velocity)
		attr = entity.entity_data.find_attribute("BaseVel")
		if attr:
			attr.force_set_base_value(vel_info.BaseVel)
		# 记录StateManager需要的参数
		var state_component:StateComponent = entity.get_component(StateComponent)
		if state_component:
			var state_chart:StateChart = state_component.get_state_chart_manager().chart
			if state_chart:
				var property_name = "Runtime_{0}".format(["Speed"])
				var last_speed = state_chart.get_expression_property(property_name)
				if last_speed != entity.entity_data.get_attribute_value("Vel").length():
					state_chart.set_expression_property(property_name,entity.entity_data.get_attribute_value("Vel").length())
	elif root is StaticBody2D:
		pass
func _notification(what: int) -> void:
	if what == NOTIFICATION_PREDELETE:
		Utils.array_call_method(controller_additional_effects,"cancel_excute")
		controller_command_manager.destroy()
		if controller:
			controller.unregister_key_action_event(_on_controller_key_action_state_changed)
		if key_action_state_changed.is_connected(on_key_action_state_changed):
			key_action_state_changed.disconnect(on_key_action_state_changed)
#endregion
